﻿
#include <iostream>

//c/c++ code
#include <stdio.h>
#include <io.h> 
#include <windows.h>
#include <tlhelp32.h>
#include <string>
#include <tchar.h>
#include <Psapi.h>
#include <conio.h>
#include <iostream>
#include "resource.h"

#include "功能函数.h"
#include "结构.h"

#pragma comment (lib,"Psapi.lib")

DWORD   ProcessId = 0;
UINT64  nRet64 = 0;
DWORD   lpexitCode = 0;

DWORD   ThreadId = 0;
SIZE_T  nWriten = 0;
HWND    hWnd = FindWindowA("Galaxy2DEngine", NULL);  //设置注入的目标窗口句柄

extern TCHAR   configPath[MAX_PATH];
extern TCHAR   dllPath[MAX_PATH] ;

BOOL DosPathToNtPath(LPTSTR pszDosPath, LPTSTR pszNtPath)
{
    TCHAR            szDriveStr[500];
    TCHAR            szDrive[3];
    TCHAR            szDevName[100];
    INT                cchDevName;
    INT                i;

    //检查参数
    if (!pszDosPath || !pszNtPath)
        return FALSE;

    //获取本地磁盘字符串
    if (GetLogicalDriveStrings(sizeof(szDriveStr), szDriveStr))
    {
        for (i = 0; szDriveStr[i]; i += 4)
        {
            if (!lstrcmpi(&(szDriveStr[i]), "A:\\") || !lstrcmpi(&(szDriveStr[i]), "B:\\"))
                continue;

            szDrive[0] = szDriveStr[i];
            szDrive[1] = szDriveStr[i + 1];
            szDrive[2] = '\0';
            if (!QueryDosDevice(szDrive, szDevName, 100))//查询 Dos 设备名
                return FALSE;

            cchDevName = lstrlen(szDevName);
            if (_tcsnicmp(pszDosPath, szDevName, cchDevName) == 0)//命中
            {
                lstrcpy(pszNtPath, szDrive);//复制驱动器
                lstrcat(pszNtPath, pszDosPath + cchDevName);//复制路径

                return TRUE;
            }
        }
    }

    lstrcpy(pszNtPath, pszDosPath);

    return FALSE;
}
//获取进程完整路径
BOOL GetProcessFullPath(DWORD dwPID, TCHAR pszFullPath[MAX_PATH])
{
    TCHAR        szImagePath[MAX_PATH];
    HANDLE        hProcess;
    if (!pszFullPath)
        return FALSE;

    pszFullPath[0] = '\0';
    hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, 0, dwPID);
    if (!hProcess)
        return FALSE;

    if (!GetProcessImageFileName(hProcess, szImagePath, MAX_PATH))
    {
        CloseHandle(hProcess);
        return FALSE;
    }

    if (!DosPathToNtPath(szImagePath, pszFullPath))
    {
        CloseHandle(hProcess);
        return FALSE;
    }

    CloseHandle(hProcess);

    _tprintf(_T("%d,%s \r\n"), dwPID, pszFullPath);
    return TRUE;
}


bool FreeResFile(unsigned long m_lResourceID, const char* m_strResourceType, const char* m_strFileName)
{
    //构造完整释放文件路径
    /*char strFullPath[MAX_DLL_PATH] = { 0 };
    sprintf_s(strFullPath, "%s\\%s", this->m_filePath, m_strFileName);
    */

    HMODULE tmHmodule = ::GetModuleHandle(NULL);

    //查找资源
    HRSRC hResID = ::FindResource(tmHmodule, MAKEINTRESOURCE(m_lResourceID), m_strResourceType);
    //加载资源  
    HGLOBAL hRes = ::LoadResource(tmHmodule, hResID);
    //锁定资源
    LPVOID pRes = ::LockResource(hRes);

    if (pRes == NULL)  return FALSE;

    //得到待释放资源文件大小 
    unsigned long dwResSize = ::SizeofResource(tmHmodule, hResID);

    //创建文件 
    HANDLE hResFile = CreateFile(m_strFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if (INVALID_HANDLE_VALUE == hResFile)   return FALSE;

    DWORD dwWrited = 0;
    if (FALSE == WriteFile(hResFile, pRes, dwResSize, &dwWrited, NULL))  return FALSE;

    CloseHandle(hResFile);
    UnlockResource(hRes);
    FreeResource(hRes);    
    return TRUE;
}


using namespace std;

void GetGamePath()
{
    //printf("游戏路径：GetGamePath -> %s\n", exeFullPath);
    GetWindowThreadProcessId(hWnd, &ProcessId);
    TCHAR   szProcessName[MAX_PATH] = { 0 };
    
    GetProcessFullPath(ProcessId, szProcessName);  
    printf("游戏路径：GetGamePath -> %s\n", szProcessName);
   
    char* p = NULL;
    p = strrchr(szProcessName, '\\');    * p = '\0';
    int len = strlen(szProcessName);
    string path = "\\NiceGG.ini";                    //配置文件名
    ::strcpy(szProcessName + len, path.c_str());     //组合出配置文件的全路径

    ::strcpy(configPath, szProcessName);
    ::strcpy(dllPath, szProcessName);

    p = strrchr(dllPath, '\\');    *p = '\0';
    len = strlen(dllPath);
    path = "\\MineDX9Pro.dll";
    ::strcpy(dllPath + len, path.c_str());
    
    if (access(configPath,0) <= 0)
        CreateFile(configPath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    
    if (access(dllPath, 0) <= 0)      
        FreeResFile(IDR_DLL2, "DLL", dllPath);

  



    printf("\n成功找到游戏进程，进行游戏数据初始化.....\n\n");
    //printf("配置路径：GetGamePath -> %s\n", szProcessName);
    //printf("配置路径：configPath -> %s\n", configPath);
    //printf("配置路径：dllPath -> %s\n", dllPath);


}


UINT64 RemoteDll(char* fullDllPathName)
{
    //printf("WindHwnd \t=> \t%016llX \r\n", (UINT64)hWnd);
    if (!hWnd) return 0;

    // 获取目标进程ID
    GetWindowThreadProcessId(hWnd, &ProcessId);
    //printf("ProcessId \t=> \t%016llX \r\n", (UINT64)ProcessId);

    // 获取目标进程窗口句柄
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessId);
    //printf("hProcess \t=> \t%016llX \r\n", (UINT64)hProcess);
    if (!hProcess) return 0;


    LPVOID tempAdrs = VirtualAllocEx(hProcess, NULL, 1024, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    //printf("tempAdrs \t=> \t%016llX \r\n", (UINT64)tempAdrs);
    if (!tempAdrs) return 0;


    WriteProcessMemory(hProcess, tempAdrs, fullDllPathName, strlen(fullDllPathName) + 1, &nWriten);

    // 线程注入
    HANDLE ht = CreateRemoteThread(
        hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibraryA,
        tempAdrs, 0, &ThreadId
    );

    //printf("ThreadHandle \t=> \t%016llX \r\n", (UINT64)ht);
    if (!ht) return 0;

    //WaitForSingleObject(ht, 0xffffffff);
    //GetExitCodeThread(ht, &lpexitCode);

    nRet64 = (UINT64)ht;
    return nRet64;
}


int main()
{
    // 获取当前目录
    char tmpPath[256] = { 0 };
    GetCurrentDirectoryA(256, tmpPath);

    // 拼接完整DLL路径
    //strcat_s(tmpPath,"\\MineDX9Pro.dll");
    //strcat_s(tmpPath, "\\NineDX12.dll");
    //printf("注入器路径： %s \r\n", tmpPath);
    if (hWnd)
    {
        GetGamePath();

        T地址储存 a;
        a.c初始化();
        // 执行注入
        printf("\n\n数据初始化完成，可以关闭本窗口了...\n");
        if (!RemoteDll(dllPath)) printf("注入失败！！ \r\n");        
    }
    else
    {
        printf("游戏没打开,记得一定要用管理员方式打开辅助！！！\n");
    }

    getch();
}

